package com.yupi.springbootinit.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.springbootinit.annotation.OperationLog;
import com.yupi.springbootinit.common.BaseResponse;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.common.ResultUtils;
import com.yupi.springbootinit.constant.AttachmentConstant;
import com.yupi.springbootinit.model.dto.workflow.*;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.mapper.WorkflowTaskMapper;
import com.yupi.springbootinit.model.entity.*;
import com.yupi.springbootinit.model.vo.AttachmentVO;
import com.yupi.springbootinit.model.vo.TaskOperationLogVO;
import com.yupi.springbootinit.model.vo.PersonalTaskStatsVO;
import com.yupi.springbootinit.model.vo.WorkflowTaskVO;
import com.yupi.springbootinit.service.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 工作流待办任务接口
 */
@RestController
@RequestMapping("/workflowTask")
@Slf4j
public class WorkflowTaskController {

    @Resource
    private WorkflowTaskService workflowTaskService;

    @Resource
    private UserService userService;

    @Resource
    private AttachmentService attachmentService;

    @Resource
    private DepartmentService departmentService;

    @Resource
    private WorkflowTaskMapper workflowTaskMapper;

    @Resource
    private ProcessBatchService processBatchService;

    @Resource
    private ProductionOperationRecordService productionOperationRecordService;

    @Resource
    private TaskOperationLogService taskOperationLogService;

    /**
     * 部门待办分页查询（按当前用户部门过滤）
     */
    @PostMapping("/list/page")
    public BaseResponse<Page<WorkflowTaskVO>> listDepartmentTasks(@RequestBody QueryRequest req, HttpServletRequest request) {
        if (req == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long current = req.getPageNum() == null ? 1L : req.getPageNum();
        long size = req.getPageSize() == null ? 10L : req.getPageSize();
        if (size > 50) {
            size = 50;
        }
        String status = StringUtils.trimToNull(req.getStatus());

        User loginUser = userService.getLoginUser(request);
        Long deptId = loginUser.getDepartmentId();
        if (deptId == null) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "缺少部门信息");
        }
        Page<WorkflowTaskVO> page = workflowTaskService.pageDepartmentTasksVO(deptId, status, current, size, loginUser);
        return ResultUtils.success(page);
    }

    /**
     * 认领待办（并发防护：仅PENDING且未被认领时成功）
     * 注意：PUBLISH_BATCH类型任务不允许认领
     */
    @PostMapping("/claim")
    @OperationLog(operation = "认领", module = "待办任务")
    public BaseResponse<Boolean> claimTask(@RequestParam Long taskId, HttpServletRequest request) {
        if (taskId == null || taskId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "taskId无效");
        }
        User loginUser = userService.getLoginUser(request);
        Long deptId = loginUser.getDepartmentId();
        if (deptId == null) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "缺少部门信息");
        }
        
        // ✅ 权限检查：验证用户是否可以认领该任务
        if (!workflowTaskService.checkCanClaim(taskId, loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权认领该任务，请检查任务状态、部门权限或任务类型");
        }
        
        boolean ok = workflowTaskService.claimTask(taskId, loginUser.getId(), loginUser.getUserName(), deptId);
        if (ok) {
            // 写任务操作日志（CLAIM）
            taskOperationLogService.log(taskId, "CLAIM", loginUser.getUserName(), "认领任务", java.time.LocalDateTime.now());
        }
        if (!ok) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "认领失败，任务可能已被他人认领、状态不允许或该类型任务不支持认领");
        }
        return ResultUtils.success(true);
    }

    /**
     * 查询我的待办任务（已认领的任务）
     */
    @PostMapping("/my/page")
    public BaseResponse<Page<WorkflowTaskVO>> listMyTasks(@RequestBody QueryRequest req, HttpServletRequest request) {
        if (req == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long current = req.getPageNum() == null ? 1L : req.getPageNum();
        long size = req.getPageSize() == null ? 10L : req.getPageSize();
        if (size > 50) {
            size = 50;
        }
        String status = StringUtils.trimToNull(req.getStatus());

        User loginUser = userService.getLoginUser(request);
        Page<WorkflowTaskVO> page = workflowTaskService.pageMyTasks(loginUser.getId(), status, current, size, loginUser);
        return ResultUtils.success(page);
    }

    /**
     * 开始待办任务
     */
    @PostMapping("/start")
    @OperationLog(operation = "开始", module = "待办任务")
    public BaseResponse<Boolean> startTask(@RequestBody StartTaskRequest req, HttpServletRequest request) {
        if (req == null || req.getTaskId() == null || req.getTaskId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "taskId无效");
        }
        if (req.getOperatorId() == null && (req.getOperatorName() == null || req.getOperatorName().isEmpty())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "实际操作者信息不能为空");
        }
        User loginUser = userService.getLoginUser(request);
        
        // ✅ 权限检查：验证用户是否可以处理该任务
        if (!workflowTaskService.checkCanProcess(req.getTaskId(), loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权处理该任务，请确认任务已认领且属于您的部门");
        }
        
        boolean ok = workflowTaskService.startTask(req.getTaskId(), req.getOperatorId(), req.getOperatorName(),
                loginUser.getId(), loginUser.getUserName(), req.getRemark());
        if (!ok) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "开始任务失败，请检查任务状态");
        }
        return ResultUtils.success(true);
    }

    @PostMapping("/complete")
    @OperationLog(operation = "完成", module = "待办任务")
    public BaseResponse<Boolean> completeTask(@RequestBody CompleteTaskRequest req, HttpServletRequest request) {
        if (req == null || req.getTaskId() == null || req.getTaskId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "taskId无效");
        }
        if (req.getOperatorId() == null && (req.getOperatorName() == null || req.getOperatorName().isEmpty())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "实际操作者信息不能为空");
        }
        User loginUser = userService.getLoginUser(request);
        
        // ✅ 权限检查：验证用户是否可以完成该任务
        if (!workflowTaskService.checkCanComplete(req.getTaskId(), loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权完成该任务，请确认任务状态为进行中且已被您认领");
        }
        
        boolean ok = workflowTaskService.completeTask(req.getTaskId(), req.getOperatorId(), req.getOperatorName(),
                loginUser.getId(), loginUser.getUserName(), req.getRemark());
        if (!ok) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "完成任务失败，请检查任务状态");
        }
        return ResultUtils.success(true);
    }

    /**
     * 获取待办任务统计（部门+个人综合统计）
     */
    @GetMapping("/statistics")
    public BaseResponse<TaskStatistics> getTaskStatistics(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        Long deptId = loginUser.getDepartmentId();
        if (deptId == null) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "缺少部门信息");
        }
        TaskStatistics statistics = workflowTaskService.getTaskStatistics(deptId, loginUser.getId());
        return ResultUtils.success(statistics);
    }

    /**
     * 获取个人任务统计（专用于个人任务中心）
     */
    @GetMapping("/statistics/personal")
    public BaseResponse<PersonalTaskStatsVO> getPersonalTaskStatistics(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        PersonalTaskStatsVO statistics = workflowTaskService.getPersonalTaskStats(loginUser.getId());
        return ResultUtils.success(statistics);
    }

    /**
     * 查询父任务下的所有子任务
     * 主要用于：PMC排期任务展开查看批次发布子任务
     * 
     * @param parentTaskId 父任务ID
     * @return 子任务列表
     */
    @GetMapping("/{parentTaskId}/subtasks")
    public BaseResponse<List<WorkflowTaskVO>> listSubTasks(@PathVariable Long parentTaskId, HttpServletRequest request) {
        if (parentTaskId == null || parentTaskId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "parentTaskId无效");
        }
        // 校验用户登录态
        User loginUser = userService.getLoginUser(request);
        
        // ✅ 权限检查：验证父任务是否属于当前用户部门
        WorkflowTask parentTask = workflowTaskMapper.selectById(parentTaskId);
        if (parentTask == null || (parentTask.getIsDelete() != null && parentTask.getIsDelete() == 1)) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "父任务不存在");
        }
        if (!parentTask.getDepartmentId().equals(loginUser.getDepartmentId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权查看该任务的子任务，任务不属于您的部门");
        }
        
        List<WorkflowTaskVO> subTasks = workflowTaskService.listSubTasks(parentTaskId, loginUser);
        return ResultUtils.success(subTasks);
    }

    /**
     * 查看任务关联销售订单附件（工程部 GC001 可见）
     */
    @GetMapping("/workorder/{taskId}/steps")
    public BaseResponse<List<ProcessBatchStep>> listWorkorderSteps(@PathVariable Long taskId, HttpServletRequest request) {
        if (taskId == null || taskId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "taskId无效");
        }
        User loginUser = userService.getLoginUser(request);
        WorkflowTask task = workflowTaskMapper.selectById(taskId);
        if (task == null || (task.getIsDelete() != null && task.getIsDelete() == 1)) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "任务不存在");
        }
        
        // ✅ 权限检查：验证任务是否属于当前用户部门
        if (!task.getDepartmentId().equals(loginUser.getDepartmentId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权查看该任务的工序，任务不属于您的部门");
        }
        
        if (!"PROCESS_BATCH".equals(task.getBizType())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "仅支持版次工单任务");
        }
        List<ProcessBatchStep> steps = processBatchService.listSteps(task.getBizId());
        return ResultUtils.success(steps);
    }

    @PostMapping("/workorder/step/start")
    @OperationLog(operation = "开始", module = "生产工单-工序")
    public BaseResponse<Boolean> startWorkorderStep(@RequestBody WorkorderStepStartRequest req, HttpServletRequest request) {
        if (req == null || req.getTaskId() == null || req.getStepId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "taskId/stepId不能为空");
        }
        if (req.getOperatorId() == null && (req.getOperatorName() == null || req.getOperatorName().isEmpty())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "实际操作者信息不能为空");
        }
        User loginUser = userService.getLoginUser(request);
        WorkflowTask task = workflowTaskMapper.selectById(req.getTaskId());
        if (task == null || (task.getIsDelete() != null && task.getIsDelete() == 1)) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "任务不存在");
        }
        
        // ✅ 权限检查：验证任务是否属于当前用户部门
        if (!task.getDepartmentId().equals(loginUser.getDepartmentId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权操作该任务的工序，任务不属于您的部门");
        }
        
        if (!"PROCESS_BATCH".equals(task.getBizType())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "仅支持版次工单任务");
        }

        // 更新工序实际开始与状态（首个START生效）
        boolean ok = processBatchService.markStepStarted(task.getBizId(), req.getStepId());
        // 写审计
        productionOperationRecordService.recordStart(req.getTaskId(), task.getBizId(), req.getStepId(),
                null, "PROCESS_EXECUTION", req.getOperatorId(), req.getOperatorName(),
                loginUser.getId(), loginUser.getUserName(), req.getRemark());
        return ResultUtils.success(ok);
    }

    @PostMapping("/workorder/step/complete")
    @OperationLog(operation = "完成", module = "生产工单-工序")
    public BaseResponse<Boolean> completeWorkorderStep(@RequestBody WorkorderStepCompleteRequest req, HttpServletRequest request) {
        if (req == null || req.getTaskId() == null || req.getStepId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "taskId/stepId不能为空");
        }
        if (req.getOperatorId() == null && (req.getOperatorName() == null || req.getOperatorName().isEmpty())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "实际操作者信息不能为空");
        }
        User loginUser = userService.getLoginUser(request);
        WorkflowTask task = workflowTaskMapper.selectById(req.getTaskId());
        if (task == null || (task.getIsDelete() != null && task.getIsDelete() == 1)) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "任务不存在");
        }
        
        // ✅ 权限检查：验证任务是否属于当前用户部门
        if (!task.getDepartmentId().equals(loginUser.getDepartmentId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权操作该任务的工序，任务不属于您的部门");
        }
        
        if (!"PROCESS_BATCH".equals(task.getBizType())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "仅支持版次工单任务");
        }

        // 更新工序实际结束与状态（首个COMPLETE生效）
        boolean ok = processBatchService.markStepCompleted(task.getBizId(), req.getStepId());
        // 写审计
        productionOperationRecordService.recordComplete(req.getTaskId(), task.getBizId(), req.getStepId(),
                null, "PROCESS_EXECUTION", req.getOperatorId(), req.getOperatorName(),
                loginUser.getId(), loginUser.getUserName(), req.getRemark());
        return ResultUtils.success(ok);
    }

    @GetMapping("/{taskId}/operationLogs")
    public BaseResponse<List<TaskOperationLogVO>> getTaskOperationLogs(@PathVariable Long taskId, HttpServletRequest request) {
        if (taskId == null || taskId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "taskId无效");
        }
        User loginUser = userService.getLoginUser(request);
        
        // ✅ 权限检查：验证任务是否属于当前用户部门
        WorkflowTask task = workflowTaskMapper.selectById(taskId);
        if (task == null || (task.getIsDelete() != null && task.getIsDelete() == 1)) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "任务不存在");
        }
        if (!task.getDepartmentId().equals(loginUser.getDepartmentId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权查看该任务的操作日志，任务不属于您的部门");
        }
        
        List<TaskOperationLogVO> logs = taskOperationLogService.listByTaskId(taskId);
        return ResultUtils.success(logs);
    }

    @GetMapping("/{taskId}/attachments")
    public BaseResponse<List<AttachmentVO>> listTaskAttachments(@PathVariable Long taskId, HttpServletRequest request) {
        if (taskId == null || taskId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "taskId无效");
        }
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null || loginUser.getDepartmentId() == null) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "缺少部门信息");
        }

        WorkflowTask task = workflowTaskMapper.selectById(taskId);
        if (task == null || (task.getIsDelete() != null && task.getIsDelete() == 1)) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "任务不存在");
        }
        
        // ✅ 权限检查：使用统一的权限检查方法
        if (!workflowTaskService.checkCanViewAttachment(taskId, loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权查看该任务的附件，仅工程部可查看销售订单附件");
        }
        
        if (!AttachmentConstant.BizType.SALES_ORDER.equals(task.getBizType())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "当前任务不属于销售订单，无法查询附件");
        }
        Long bizId = task.getBizId();
        List<Attachment> list = attachmentService.getAttachmentsByBiz(AttachmentConstant.BizType.SALES_ORDER, bizId);
        List<AttachmentVO> voList = list.stream().map(attachmentService::getAttachmentVO).collect(Collectors.toList());
        return ResultUtils.success(voList);
    }

    // WorkflowTaskController.java

    /**
     * 获取当前用户已认领的创建工艺单任务
     */
    @GetMapping("/my/processSheet/claimed")
    public BaseResponse<List<WorkflowTaskVO>> getMyClaimedProcessSheetTasks(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);

        // ✅ 调用 Service 方法
        List<WorkflowTask> tasks = workflowTaskService.getMyClaimedProcessSheetTasks(loginUser.getId());

        // 转换为VO
        List<WorkflowTaskVO> taskVOs = tasks.stream()
                .map(task -> {
                    WorkflowTaskVO vo = new WorkflowTaskVO();
                    BeanUtils.copyProperties(task, vo);
                    workflowTaskService.calculateTaskPermissions(vo, loginUser);
                    return vo;
                })
                .collect(Collectors.toList());

        log.info("查询已认领的工艺单任务: userId={}, count={}", loginUser.getId(), taskVOs.size());

        return ResultUtils.success(taskVOs);
    }


    public static class TaskStatistics {
        private Long departmentPendingCount; // 部门待认领任务数
        private Long departmentInProgressCount; // 部门进行中任务数
        private Long departmentDoneCount; // 部门已完成任务数
        private Long myPendingCount; // 我的待处理任务数
        private Long myInProgressCount; // 我的进行中任务数
        private Long myDoneCount; // 我的已完成任务数
        private Long overdueCount; // 逾期任务数
    }
}